package com.example.online_search_springboot.searcher;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;

public class Parser {
    private Index index = new Index();
    public static final String INPUT_PATH = "C:/Users/Administrator/Desktop/online_search_doc/jdk-8u341-docs-all/docs/api/";

    private AtomicLong t1 = new AtomicLong(0);
    private AtomicLong t2 = new AtomicLong(0);


    //多线程制作索引
    public void runByThread() throws InterruptedException {
        long begin = System.currentTimeMillis();
        System.out.println("索引制作开始！");

        ArrayList<File> files = new ArrayList<>();
        enumFile(INPUT_PATH, files);

        //引入线程池
        ExecutorService executorService = Executors.newFixedThreadPool(8);
        CountDownLatch countDownLatch = new CountDownLatch(files.size());
        for (File f : files) {
            //通过submit往线程池中提交任务，这个操作很快（只是把这个Runnable对象放到阻塞队列中）
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("开始解析：" + f.getAbsolutePath());
                    parseHtml(f);
                    countDownLatch.countDown();
                }
            });
        }
        countDownLatch.await();
        executorService.shutdown();
        //此处必须要等待所有的线程把所有的文件处理完，才能进行save索引操作。
        index.save();

        long end = System.currentTimeMillis();
        System.out.println("索引制作完成！ 消耗时间：" + (end - begin) + "ms");
        System.out.println("t1: " + t1 + "  ,  t2   " + t2);
    }

//    public void run() {
//        long begin = System.currentTimeMillis();
//        System.out.println("索引制作开始！");
//        //1.枚举出所有的.html文件，包括子目录中的文件
//        ArrayList<File> filelist = new ArrayList<>();
//        enumFile(INPUT_PATH, filelist);
//        long endEnumFile = System.currentTimeMillis();
//        System.out.println("枚举文件完成！消耗时间： " + (endEnumFile - begin) + "ms");
////        System.out.println(filelist);
////        System.out.println(filelist.size());
//        //2.针对上面罗列出的文档路径，打开文件，读取文件内容，进行解析，构建索引
//        for (File f : filelist) {
//            System.out.println("开始解析：" + f.getAbsolutePath());
//            parseHtml(f);
//        }
//        long endFor = System.currentTimeMillis();
//        System.out.println("遍历文件完成！消耗时间：" + (endFor - endEnumFile) + "ms");
//        //3.把在内存中构造好的索引数据结构，保存到指定的文件中
//        index.save();
//        long end = System.currentTimeMillis();
//        System.out.println("索引制作完成！消耗时间： " + (end - begin) + " ms");
//    }

    private void parseHtml(File f) {
        //解析标题
        String title = parseTitle(f);
        //解析url
        String url = parseUrl(f);

        long begin = System.nanoTime();
        //解析正文
        String content = parseContent(f);

        long mid = System.nanoTime();

        // TODO: 把解析出来的这些信息，加入到索引当中
        index.addDoc(title, url, content);

        long end = System.nanoTime();

        t1.addAndGet(mid - begin);
        t2.addAndGet(end - mid);
    }

    public String parseContent(File f) {
        try (BufferedReader bufferedReader = new BufferedReader(new FileReader(f))) {
            StringBuilder content = new StringBuilder();
            while (true) {
                int ret = bufferedReader.read();
                if (ret == -1) {
                    break;
                }
                char c = (char) ret;
                content.append(c);
            }
            String scriptRegex = "<script[^>]*?>[\\s\\S]*?<\\/script>";
            //定义style的正则表达式，去除style样式，防止css代码过多时只截取到css样式代码
            String styleRegex = "<style[^>]*?>[\\s\\S]*?<\\/style>";
            //定义HTML标签的正则表达式，去除标签，只提取文字内容
            String htmlRegex = "<[^>]+>";
            //定义回车,换行符,制表符
            String spaceRegex = "\t|\r|\n";

            String content_final = content.toString();
            content_final = content_final.replaceAll(scriptRegex, "");
            content_final = content_final.replaceAll(styleRegex, "");
            content_final = content_final.replaceAll(htmlRegex, "");
            content_final = content_final.replaceAll(spaceRegex, "");

            return content_final;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String parseUrl(File f) {
        String part1 = "https://docs.oracle.com/javase/8/docs/api/";
        String part2 = f.getAbsolutePath().substring(INPUT_PATH.length());
        String path = (part1 + part2).replaceAll("\\\\", "/");
        return path;
    }

    private String parseTitle(File f) {
        String name = f.getName();
        return name.substring(0, f.getName().length() - ".html".length());
    }

    private void enumFile(String inputPath, ArrayList<File> filelist) {
        File rootPath = new File(inputPath);
        File[] files = rootPath.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                enumFile(f.getAbsolutePath(), filelist);
            } else {
                if (f.getAbsolutePath().endsWith(".html")) {
                    filelist.add(f);
                }
            }
        }
    }

//    public static void main(String[] args) throws InterruptedException {
//        Parser parser = new Parser();
//        //parser.run();
//        parser.runByThread();
//    }
}
